#include <stdio.h>
#include <stdlib.h>
#include "main.h"
#include "state.h"
#include "point.h"

/*
 * Alokuje nový stav na heapě pro zadanou hloubku.
 */
State *allocateState(int depth){
	State *state = (State *)malloc(sizeof(State));
	if(state == NULL){
    	fprintf(stderr, "Out of memory during allocating new state.\n");
	}
	state->depth = depth;
	if(depth > 0){
		state->statePoints = (Point *)malloc(depth * sizeof(Point));
		if(state->statePoints == NULL){
    		fprintf(stderr, "Out of memory during allocating new state.\n");
		}
	}
	return state;
}

/*
 * Alokuje nový stav na heapě s hloubkou zadaného stavu + 1. Dále zkopíruje
 * stavy z rodičovského stavu do potomka.
 */
State *childState(State* state){
	State *child = allocateState(state->depth + 1);
	int i;
	for(i = 0; i < state->depth; i++){
		child->statePoints[i] = state->statePoints[i];
	}
	return child;
}

/*
 * Odstraní stav z heapy.
 */
void freeState(State *state){
	if(state->depth > 0){
		free(state->statePoints);
	}
	free(state);
}

/*
 * Výpíše zadaný stav.
 */
void printState(State *state){
	if(state == NULL){
		printf("Provided state is NULL!");
		return;
	}

	/* TODO předělat na pole charů, které se postupně naplní */
	printf("State with depth %d: ", state->depth);
	int i;
	for(i = 0; i < state->depth; i++){
		Point point = state->statePoints[i];
		printf("[%d, %d]", point.x, point.y);
	}
	printf("\n");
}

/*
 * Pro zadaný stav spočítá sumu euklidovských vzdáleností mezi fixními a
 * umístěnými body a mezi umístěnými body navzájem.
 */
double evaluateState(State *state){
	double result = 0;
	int i, j;

	for(i = 0; i < state->depth; i++){
		for(j = 0; j < f; j++){
			result += countDistance(state->statePoints[i], fixedPoints[j]);
		}
	}

	for(i = 0; i < state->depth; i++){
		for(j = i+1; j < state->depth; j++){
			result += countDistance(state->statePoints[i], state->statePoints[j]);
		}
	}
	return result;
}
